package com.cdtu.outtake.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.net.SSLUtil;
import com.alibaba.fastjson.JSON;
import com.cdtu.outtake.MyException;
import com.cdtu.outtake.dao.UserDao;
import com.cdtu.outtake.domain.User;
import com.cdtu.outtake.service.ILoginService;
import com.cdtu.outtake.util.SslUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Map;
import java.util.Optional;

/**
 * @Author : shl
 * @Date 2024/3/2 14:07
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class LoginServiceImpl implements ILoginService {
    private final RestTemplate restTemplate;
    private final UserDao userDao;
    @Value("${wx.grant-type}")
    private String grantType;
    @Value("${wx.app-id}")
    private String appId;
    @Value("${wx.secret}")
    private String secret;

    @Override
    public String getWxAccessToken() {
        String url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=%s&appid=%s&secret=%s", grantType, appId, secret);
        String json = restTemplate.getForObject(url, String.class);
        return JSON.parseObject(json).getString("access_token");
    }

    @Override
    public Long getWxUserPhone(String accessToken, String code) {
        String url = String.format("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s", accessToken);
        HttpEntity<Map<String, String>> httpEntity = new HttpEntity<>(Map.of("code", code), new HttpHeaders());
        String json = restTemplate.postForObject(url, httpEntity, String.class);

        return Optional.ofNullable(JSON.parseObject(json))
                .map(jsonObject -> jsonObject.getJSONObject("phone_info"))
                .map(jsonObject -> jsonObject.getString("purePhoneNumber"))
                .map(Long::valueOf)
                .orElseThrow(() -> new MyException("手机号获取失败"));
    }

    @Override
    public String getOpenIdAndSessionKey(String code) throws Exception {
        String url = String.format("https://api.weixin.qq.com/sns/jscode2session?grant_type=%s&appid=%s&secret=%s&js_code=%s",
                "authorization_code", appId, secret, code);
        SslUtils.ignoreSsl();
        return restTemplate.getForObject(url, String.class);
    }

    @Override
    public User wxLogin(String phoneCode) {
        Long phone;
        if (phoneCode == null) {
            phone = 18234578765L;
        } else {
            phone = getWxUserPhone(getWxAccessToken(), phoneCode);
        }
        User user = userDao.findByPhone(phone);
        if (user != null) {
            StpUtil.login(user.getPhone());
            StpUtil.getSession().set("userInfo", user);
            return user;
        }
        return userRegistry(phone);
    }

    private User userRegistry(Long phone) {
        User user = User.builder()
                .phone(phone)
                .build();
        //TODO
//        userDao.insert(user);
        user = userDao.save(user);
        StpUtil.login(user.getPhone());
        StpUtil.getSession().set("userInfo", user);
        return user;
    }
}
